package com.genexususa.eo.bing.connection;

import com.genexususa.eo.bing.CampaignManagementServiceClasses.*;
import com.genexususa.eo.bing.data.*;
import com.genexususa.eo.bing.data.Util;
import com.genexususa.eo.bing.data.wsSubclasses.GxAdGroupCriterion;
import com.genexususa.eo.google.data.*;
import com.genexususa.eo.google.data.Error;
import org.xml.sax.SAXException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.rpc.ServiceException;
import java.io.IOException;
import java.io.StringWriter;
import java.rmi.RemoteException;
import java.util.HashMap;

public class AdGroupCriterionManager {
    public AdGroupCriterionManager() {
    }

    public String addAdGroupCriterions(long customerAccountId, String adGroupCriterionsXML) {

        ICampaignManagementService campaignManagement = null;
        CampaignManagementServiceLocator campaignServiceLocator = null;
        BasicHttpBinding_ICampaignManagementServiceStub stub = null;
        AddAdGroupCriterionsRequest addAdGroupCriterionsRequest = null;
        AddAdGroupCriterionsResponse addAdGroupCriterionsResponse = null;
        GA_Result result = new GA_Result();
        Util util = new Util();
        AdGroupCriterion[] adGroupCriterions = null;
        try {

            HashMap<String, String> properties = Info.getBingProperties();
            String namespace = properties.get("campaignNamespace");
            String url = properties.get("campaignURL");
            String userName = properties.get("username");
            String password = properties.get("password");
            String developerToken = properties.get("developerToken");
            String customerId = properties.get("customerId");
            String applicationToken = properties.get("applicationToken");

            campaignServiceLocator = new CampaignManagementServiceLocator();
            campaignServiceLocator.setBasicHttpBinding_ICampaignManagementServiceEndpointAddress(url);
            campaignManagement = campaignServiceLocator.getBasicHttpBinding_ICampaignManagementService(); // ServiceException
            stub = (BasicHttpBinding_ICampaignManagementServiceStub) campaignManagement;

            // Set header parameters
            stub.setHeader(namespace, "UserName", userName);
            stub.setHeader(namespace, "Password", password);
            stub.setHeader(namespace, "DeveloperToken", developerToken);
            stub.setHeader(namespace, "CustomerId", customerId);
            stub.setHeader(namespace, "CustomerAccountId", customerAccountId);
            stub.setHeader(namespace, "ApplicationToken", applicationToken);

            // Set body parameters
            addAdGroupCriterionsRequest = new AddAdGroupCriterionsRequest();
            addAdGroupCriterionsRequest.setAccountId(customerAccountId);
            // Parse adGroupCriterions from XML
            adGroupCriterions = util.adGroupCriterionsFromXML(adGroupCriterionsXML); // IllegalArgumentException, GxException, ParserConfigurationException, SAXException, IOException
            addAdGroupCriterionsRequest.setAdGroupCriterions(adGroupCriterions);

            // Call WS
            addAdGroupCriterionsResponse = campaignManagement.addAdGroupCriterions(addAdGroupCriterionsRequest); // RemoteException, ApiFaultDetail, AdApiFaultDetail

            // Call succeeded with no errors

            // Create the return object
            result = new GA_Result();
            long[] adGroupCriterionIds = addAdGroupCriterionsResponse.getAdGroupCriterionIds();
            for (int i=0; i<adGroupCriterionIds.length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem();
                resultItem.CriterionGxId = ((GxAdGroupCriterion) adGroupCriterions[i]).getGxId();
                resultItem.CriterionId = adGroupCriterionIds[i];
                result.Items.add(resultItem);

                //result.addResult(i, new GxIdResult(((GxAdGroupCriterion)adGroupCriterions[i]).getGxId(), adGroupCriterionIds[i]));
            }
        } catch (ServiceException e) { // BEFORE CALL

            GA_ResultItem resultItem = new GA_ResultItem();

            ErrorsStruct es =  new ErrorsStruct();
            com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
            error.ErrorString = e.getMessage();
            error.fieldPath = e.getLocalizedMessage();
            resultItem.HasError =  true;
            es.Errors.add(error);
            resultItem.Errors = es;

            result = new GA_Result();
            result.Items.add(resultItem);

        } catch (IllegalArgumentException e) { // BEFORE CALL

            GA_ResultItem resultItem = new GA_ResultItem();

            ErrorsStruct es =  new ErrorsStruct();
            com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
            error.ErrorString = e.getMessage();
            error.fieldPath = e.getLocalizedMessage();
            resultItem.HasError =  true;
            es.Errors.add(error);
            resultItem.Errors = es;

            result = new GA_Result();
            result.Items.add(resultItem);

        } catch (GxException e) { // BEFORE CALL

            GA_ResultItem resultItem = new GA_ResultItem();

            ErrorsStruct es =  new ErrorsStruct();
            com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
            error.ErrorString = e.getMessage();
            error.fieldPath = e.getLocalizedMessage();
            resultItem.HasError =  true;
            es.Errors.add(error);
            resultItem.Errors = es;

            result = new GA_Result();
            result.Items.add(resultItem);

        } catch (ParserConfigurationException e) { // BEFORE CALL

            GA_ResultItem resultItem = new GA_ResultItem();

            ErrorsStruct es =  new ErrorsStruct();
            com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
            error.ErrorString = e.getMessage();
            error.fieldPath = e.getLocalizedMessage();
            resultItem.HasError =  true;
            es.Errors.add(error);
            resultItem.Errors = es;

            result = new GA_Result();
            result.Items.add(resultItem);

        } catch (SAXException e) { // BEFORE CALL

            GA_ResultItem resultItem = new GA_ResultItem();

            ErrorsStruct es =  new ErrorsStruct();
            com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
            error.ErrorString = e.getMessage();
            error.fieldPath = e.getLocalizedMessage();
            resultItem.HasError =  true;
            es.Errors.add(error);
            resultItem.Errors = es;

            result = new GA_Result();
            result.Items.add(resultItem);

        } catch (ApiFaultDetail fault) { // IN CALL
            result =  new GA_Result();

            for (int i=0; i<addAdGroupCriterionsRequest.getAdGroupCriterions().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem();

                resultItem.SubCampaignGxId =  ((GxAdGroupCriterion)addAdGroupCriterionsRequest.getAdGroupCriterions()[i]).getGxId();
                resultItem.CampaignId =  ((GxAdGroupCriterion)addAdGroupCriterionsRequest.getAdGroupCriterions()[i]).getId();

                for (int h=0; h<fault.getBatchErrors().length; h++) {
                    if (fault.getBatchErrors()[h].getIndex() == null || (i == fault.getBatchErrors()[h].getIndex() && !resultItem.HasError)) {
                        resultItem.HasError = true;
                        resultItem.Errors = new ErrorsStruct();
                        com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
                        error.ErrorString = fault.getBatchErrors()[h].getErrorCode();
                        error.fieldPath = fault.getBatchErrors()[h].getMessage();
                        resultItem.Errors.Errors.add(error);
                    }
                }


                for (int h=0; h<fault.getOperationErrors().length; h++) {
                    if (!resultItem.HasError) {
                        resultItem.HasError = true;
                        resultItem.Errors = new ErrorsStruct();
                        Error error = new Error();
                        error.ErrorString = fault.getOperationErrors()[h].getErrorCode();
                        error.fieldPath = fault.getOperationErrors()[h].getMessage();
                        resultItem.Errors.Errors.add(error);
                    }
                }

                result.Items.add(resultItem);
            }
        } catch (AdApiFaultDetail fault) { // IN CALL
            for (int i=0; i<addAdGroupCriterionsRequest.getAdGroupCriterions().length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem();
                resultItem.SubCampaignGxId =  ((GxAdGroupCriterion)addAdGroupCriterionsRequest.getAdGroupCriterions()[i]).getGxId();
                resultItem.CampaignId =  ((GxAdGroupCriterion)addAdGroupCriterionsRequest.getAdGroupCriterions()[i]).getId();

                ErrorsStruct es =  new ErrorsStruct();
                for(int x=0; x < fault.getErrors().length; x++){
                    com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
                    error.ErrorString = fault.getErrors()[x].getDetail();
                    error.fieldPath = fault.getErrors()[x].getMessage();

                    es.Errors.add(error);
                }

                resultItem.HasError =  true;
                resultItem.Errors = es;

                result.Items.add(resultItem);

            }

        } catch (RemoteException e) { // IN CALL
            for (int i=0; i<addAdGroupCriterionsRequest.getAdGroupCriterions().length; i++) {

                GA_ResultItem resultItem = new GA_ResultItem();
                resultItem.CriterionGxId = ((GxAdGroupCriterion)addAdGroupCriterionsRequest.getAdGroupCriterions()[i]).getGxId();
                resultItem.CriterionId =  ((GxAdGroupCriterion)addAdGroupCriterionsRequest.getAdGroupCriterions()[i]).getId();

                ErrorsStruct es =  new ErrorsStruct();
                com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
                error.ErrorString = e.getMessage();
                error.fieldPath = e.getLocalizedMessage();
                resultItem.HasError =  true;
                es.Errors.add(error);
                resultItem.Errors = es;

                result.Items.add(resultItem);

                //result.getAdGroupsResultCollection()[j].addAdGroupResult(i, ((GxAdGroup)adGroupsRequests[j].getAdGroups()[i]).getGxId());
            }
        } catch (IOException e) { // BEFORE CALL

            GA_ResultItem resultItem = new GA_ResultItem();

            ErrorsStruct es =  new ErrorsStruct();
            com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
            error.ErrorString = e.getMessage();
            error.fieldPath = e.getLocalizedMessage();
            resultItem.HasError =  true;
            es.Errors.add(error);
            resultItem.Errors = es;

            result = new GA_Result();
            result.Items.add(resultItem);

        }

        String returnMessage = null;
        // GxIdResults -> XML
        try {
            JAXBContext contextObj = JAXBContext.newInstance(GA_Result.class); // JAXBException

            Marshaller marshallerObj = contextObj.createMarshaller(); // JAXBException
            marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // PropertyException

            StringWriter sw = new StringWriter();

            marshallerObj.marshal(result, sw); // JAXBException
            returnMessage = sw.getBuffer().toString();
        }  catch (PropertyException e) { // AFTER CALL
            returnMessage = util.getPropertyExceptionMessage(e);
        } catch (JAXBException e) { // AFTER CALL
            returnMessage = util.getJAXBExceptionMessage(e);
        }
        return returnMessage;
    }

    public String deleteAdGroupCriterions(long customerAccountId, String adGroupCriterionsXML, long adGroupId) {

        ICampaignManagementService campaignManagement = null;
        CampaignManagementServiceLocator campaignServiceLocator = null;
        BasicHttpBinding_ICampaignManagementServiceStub stub = null;
        DeleteAdGroupCriterionsRequest deleteAdGroupCriterionsRequest = null;
        GA_Result result = new GA_Result();
        Util util = new Util();
        AdGroupCriterion[] adGroupCriterions = null;
        try {
            HashMap<String, String> properties = Info.getBingProperties();
            String namespace = properties.get("campaignNamespace");
            String url = properties.get("campaignURL");
            String userName = properties.get("username");
            String password = properties.get("password");
            String developerToken = properties.get("developerToken");
            String customerId = properties.get("customerId");
            String applicationToken = properties.get("applicationToken");

            campaignServiceLocator = new CampaignManagementServiceLocator();
            campaignServiceLocator.setBasicHttpBinding_ICampaignManagementServiceEndpointAddress(url);
            campaignManagement = campaignServiceLocator.getBasicHttpBinding_ICampaignManagementService(); // ServiceException
            stub = (BasicHttpBinding_ICampaignManagementServiceStub) campaignManagement;

            // Set header parameters
            stub.setHeader(namespace, "UserName", userName);
            stub.setHeader(namespace, "Password", password);
            stub.setHeader(namespace, "DeveloperToken", developerToken);
            stub.setHeader(namespace, "CustomerId", customerId);
            stub.setHeader(namespace, "CustomerAccountId", customerAccountId);
            stub.setHeader(namespace, "ApplicationToken", applicationToken);

            // Set body parameters
            deleteAdGroupCriterionsRequest = new DeleteAdGroupCriterionsRequest();
            deleteAdGroupCriterionsRequest.setAccountId(customerAccountId);
            deleteAdGroupCriterionsRequest.setAdGroupId(adGroupId);
            // Parse adGroupCriterions from XML
            adGroupCriterions = util.adGroupCriterionsFromXML(adGroupCriterionsXML); // IllegalArgumentException, GxException, ParserConfigurationException, SAXException, IOException
            long[] adGroupCriterionIds = new long[adGroupCriterions.length];
            for (int i=0; i<adGroupCriterionIds.length; i++) {
                if (adGroupCriterions[i].getId() == null) {
                    adGroupCriterionIds[i] = -1;
                } else {
                    adGroupCriterionIds[i] = adGroupCriterions[i].getId();
                }
            }
            deleteAdGroupCriterionsRequest.setAdGroupCriterionIds(adGroupCriterionIds);

            // Call WS
            campaignManagement.deleteAdGroupCriterions(deleteAdGroupCriterionsRequest); // RemoteException, ApiFaultDetail, AdApiFaultDetail

            // Call succeeded with no errors

            // Create the return object
            result = new GA_Result();

            for (int i=0; i<adGroupCriterions.length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem();
                resultItem.CriterionGxId = ((GxAdGroupCriterion) adGroupCriterions[i]).getGxId();
                resultItem.CriterionId = (adGroupCriterions[i]).getId();

                result.Items.add(resultItem);

                //result.addResult(i, new GxIdResult(((GxAdGroupCriterion) adGroupCriterions[i]).getGxId(), adGroupCriterionIds[i]));
            }
        } catch (ServiceException e) { // BEFORE CALL
            GA_ResultItem resultItem = new GA_ResultItem();

            ErrorsStruct es =  new ErrorsStruct();
            com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
            error.ErrorString = e.getMessage();
            error.fieldPath = e.getLocalizedMessage();
            resultItem.HasError =  true;
            es.Errors.add(error);
            resultItem.Errors = es;

            result = new GA_Result();
            result.Items.add(resultItem);

        } catch (IllegalArgumentException e) { // BEFORE CALL

            GA_ResultItem resultItem = new GA_ResultItem();

            ErrorsStruct es =  new ErrorsStruct();
            com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
            error.ErrorString = e.getMessage();
            error.fieldPath = e.getLocalizedMessage();
            resultItem.HasError =  true;
            es.Errors.add(error);
            resultItem.Errors = es;

            result = new GA_Result();
            result.Items.add(resultItem);

        } catch (GxException e) { // BEFORE CALL

            GA_ResultItem resultItem = new GA_ResultItem();

            ErrorsStruct es =  new ErrorsStruct();
            com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
            error.ErrorString = e.getMessage();
            error.fieldPath = e.getLocalizedMessage();
            resultItem.HasError =  true;
            es.Errors.add(error);
            resultItem.Errors = es;

            result = new GA_Result();
            result.Items.add(resultItem);

        } catch (ParserConfigurationException e) { // BEFORE CALL


            GA_ResultItem resultItem = new GA_ResultItem();

            ErrorsStruct es =  new ErrorsStruct();
            com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
            error.ErrorString = e.getMessage();
            error.fieldPath = e.getLocalizedMessage();
            resultItem.HasError =  true;
            es.Errors.add(error);
            resultItem.Errors = es;

            result = new GA_Result();
            result.Items.add(resultItem);

        } catch (SAXException e) { // BEFORE CALL

            GA_ResultItem resultItem = new GA_ResultItem();

            ErrorsStruct es =  new ErrorsStruct();
            com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
            error.ErrorString = e.getMessage();
            error.fieldPath = e.getLocalizedMessage();
            resultItem.HasError =  true;
            es.Errors.add(error);
            resultItem.Errors = es;

            result = new GA_Result();
            result.Items.add(resultItem);

        } catch (ApiFaultDetail fault) { // IN CALL
            result =  new GA_Result();

            for (int i=0; i<adGroupCriterions.length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem();

                resultItem.CriterionGxId = ((GxAdGroupCriterion) adGroupCriterions[i]).getGxId();
                resultItem.CriterionId = (adGroupCriterions[i]).getId();

                for (int h=0; h<fault.getBatchErrors().length; h++) {
                    if (fault.getBatchErrors()[h].getIndex() == null || (i == fault.getBatchErrors()[h].getIndex() && !resultItem.HasError)) {
                        resultItem.HasError = true;
                        resultItem.Errors = new ErrorsStruct();
                        com.genexususa.eo.google.data.Error error = new Error();
                        error.ErrorString = fault.getBatchErrors()[h].getErrorCode();
                        error.fieldPath = fault.getBatchErrors()[h].getMessage();
                        resultItem.Errors.Errors.add(error);
                    }
                }


                for (int h=0; h<fault.getOperationErrors().length; h++) {
                    if (!resultItem.HasError) {
                        resultItem.HasError = true;
                        resultItem.Errors = new ErrorsStruct();
                        Error error = new Error();
                        error.ErrorString = fault.getOperationErrors()[h].getErrorCode();
                        error.fieldPath = fault.getOperationErrors()[h].getMessage();
                        resultItem.Errors.Errors.add(error);
                    }
                }

                result.Items.add(resultItem);
            }

        } catch (AdApiFaultDetail fault) { // IN CALL
            for (int i=0; i<adGroupCriterions.length; i++) {
                GA_ResultItem resultItem = new GA_ResultItem();

                resultItem.CriterionGxId = ((GxAdGroupCriterion) adGroupCriterions[i]).getGxId();
                resultItem.CriterionId = (adGroupCriterions[i]).getId();

                ErrorsStruct es =  new ErrorsStruct();
                for(int x=0; x < fault.getErrors().length; x++){
                    com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
                    error.ErrorString = fault.getErrors()[x].getDetail();
                    error.fieldPath = fault.getErrors()[x].getMessage();

                    es.Errors.add(error);
                }

                resultItem.HasError =  true;
                resultItem.Errors = es;

                result.Items.add(resultItem);

            }

        } catch (RemoteException e) { // IN CALL

            for (int i=0; i<adGroupCriterions.length; i++) {

                GA_ResultItem resultItem = new GA_ResultItem();

                resultItem.CriterionGxId = ((GxAdGroupCriterion) adGroupCriterions[i]).getGxId();
                resultItem.CriterionId = (adGroupCriterions[i]).getId();

                ErrorsStruct es =  new ErrorsStruct();
                com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
                error.ErrorString = e.getMessage();
                error.fieldPath = e.getLocalizedMessage();
                resultItem.HasError =  true;
                es.Errors.add(error);
                resultItem.Errors = es;

                result.Items.add(resultItem);

            }

        } catch (IOException e) { // BEFORE CALL

            GA_ResultItem resultItem = new GA_ResultItem();

            ErrorsStruct es =  new ErrorsStruct();
            com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();
            error.ErrorString = e.getMessage();
            error.fieldPath = e.getLocalizedMessage();
            resultItem.HasError =  true;
            es.Errors.add(error);
            resultItem.Errors = es;

            result = new GA_Result();
            result.Items.add(resultItem);

        }

        String returnMessage = null;
        // GxIdResults -> XML
        try {
            JAXBContext contextObj = JAXBContext.newInstance(GA_Result.class); // JAXBException

            Marshaller marshallerObj = contextObj.createMarshaller(); // JAXBException
            marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // PropertyException

            StringWriter sw = new StringWriter();

            marshallerObj.marshal(result, sw); // JAXBException
            returnMessage = sw.getBuffer().toString();
        }  catch (PropertyException e) { // AFTER CALL
            returnMessage = util.getPropertyExceptionMessage(e);
        } catch (JAXBException e) { // AFTER CALL
            returnMessage = util.getJAXBExceptionMessage(e);
        }
        return returnMessage;
    }
}
